﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Threading;
using System.Windows.Threading;


using System.IO;
using CMD_DKT;
using CMD.BAL.MISC;
using FolderZipper;
using System.ComponentModel;

namespace CMD_DKT.Conf
{
    /// <summary>
    /// Lógica de interacción para WndSincCatalogos.xaml
    /// </summary>
    public partial class WndSincCatalogos : Window
    {
        private SincronizaCatalogos sp = new SincronizaCatalogos();
        public Window parentWin { get; set; }
        private int actualProces = 0;
        private UpdateProgressBarDelegate updatePbDelegate;
        private delegate void UpdateProgressBarDelegate(
        System.Windows.DependencyProperty dp, Object value);
        private int Errores = 0;

        public WndSincCatalogos(Window parent)
        {
            InitializeComponent();
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            this.parentWin = parent;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //ThreadPool.QueueUserWorkItem(new WaitCallback(updateThreadProc), this);

            BackgroundWorker work = new BackgroundWorker();
            work.DoWork += delegate(object s, DoWorkEventArgs args)
                {
                    WndSincCatalogos win = sender as WndSincCatalogos;

                    win.initBar();
                    win.setMaxBar(2);
                    win.lanzarUpdate();

                };
            work.RunWorkerAsync();

        }

        static void updateThreadProc(object sender)
        {
            WndSincCatalogos win = sender as WndSincCatalogos;
            
            win.initBar();
            win.setMaxBar(2);
            win.lanzarUpdate();

        }

        private void lanzarUpdate()
        {
            try
            {                

                actualProces = 0;
                actualProces++;
                // Create a new instance of our ProgressBar Delegate that points
                // to the ProgressBar's SetValue method.
                updatePbDelegate =
                    new UpdateProgressBarDelegate(pBar.SetValue);
                Dispatcher.Invoke(updatePbDelegate,
                System.Windows.Threading.DispatcherPriority.Background, new object[] { ProgressBar.ValueProperty, Convert.ToDouble(actualProces) });
                /////////////////////////////////////////////////////////////////

                //SincronizaCatalogos sinc = new SincronizaCatalogos();

                string compartida = System.Configuration.ConfigurationManager.AppSettings["ServerDocsFolder"];
                string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                string tmpFile = appData + System.Configuration.ConfigurationManager.AppSettings["CarpetaTemporal"];

                //Elimina datos temporales
                sp.TruncateCMD_TMP_CAT_FILES();
                this.eliminarArchivos(tmpFile, "*");
                //Comprueba y descarga el archivo zip de carpeta remota
                if (this.CargarArchivoZIP(compartida, tmpFile, "CAT_*.zip"))
                {
                    this.addText("******************************************************** Carga de catalogos iniciada ************************************************************\n");
                    sp.TruncateCMD_TMP_CAT_FILES();
                    if (this.CargaArchivosTxt(tmpFile, "*.txt"))
                        sp.GuardaVersion();
                   // ((WndConfig)parentWin).txtUltimaSincCat.Text = System.DateTime.Now.ToShortDateString();
                }


                /////////////////////////////////////////////////////////////////
                actualProces++;
                Dispatcher.Invoke(updatePbDelegate,
                System.Windows.Threading.DispatcherPriority.Background, new object[] { ProgressBar.ValueProperty, Convert.ToDouble(actualProces) });
                
                this.addText("************************************************ Proceso de actualización finalizado ************************************************************\n");
                this.addText(" " + Errores +" Error(es).");
            }
            catch (Exception ex1) { this.addText("Error en la ejecución de la actualización : " + ex1.Message + "\n"); }
         }
        private void initBar()
        {
            pBar.Dispatcher.Invoke(
              System.Windows.Threading.DispatcherPriority.Normal,
              new Action(
                delegate()
                {
                    pBar.Minimum = 0;
                    pBar.Value = 0;
                }
            ));
        }
        public void addText(string text)
        {
            tbProceso.Dispatcher.Invoke(
              System.Windows.Threading.DispatcherPriority.Normal,
              new Action(
                delegate()
                {
                    tbProceso.Text += text;
                    tbProceso.ScrollToEnd();
                }
            ));
        }
        public string getText()
        {
            string ret = "";
            tbProceso.Dispatcher.Invoke(
              System.Windows.Threading.DispatcherPriority.Normal,
              new Action(
                delegate()
                {
                    ret = tbProceso.Text;
                }
            ));
            return ret;
        }
        private void setMaxBar(int max)
        {
            pBar.Dispatcher.Invoke(
              System.Windows.Threading.DispatcherPriority.Normal,
              new Action(
                delegate()
                {
                    pBar.Maximum = max;
                }
            ));
        }


        private bool CargarArchivoZIP(String dir, string dirTemp, string filtro)
        {


            /// ---------------------- Obtiene Archivo ZIP --------------------------- ///
 
            
            string[] archivosTerritorio = this.listarArchivos(dir, filtro);

            if (archivosTerritorio.Length == 0)
            {
                this.addText(" - No se encontro archivo de actualizacion en carpeta Remota \n");
                return false;
            }

            this.addText("**************************************************** Descarga de archivo zip iniciada ******************************************************************\n");
            foreach (string file in archivosTerritorio)
            {
                try
                {
                    FileInfo fkpi = new FileInfo(file);
                    string catalogo = fkpi.Name.Substring(0, (fkpi.Name.IndexOf("_")));
                    string date = file.Substring(file.LastIndexOf("_") + 1, (file.Length - 5 - file.LastIndexOf("_")));
                    long dateLong = -1;
                    try
                    {
                        dateLong = Convert.ToInt64(date);
                    }
                    catch { }

                    sp.InsertCMD_TMP_CAT_FILES(file, catalogo, dateLong);                    
                    this.addText(file + "\n");
                }
                catch (Exception ex)
                {
                    Errores++;
                    this.addText("- Error en lectura de archivo" + file + "\n" + ex.Message);
                    return false;
                }
            }


            
            //Descomprime Archivo
            sp.CompareCMD_TMP_CAT_FILES();
            DataTable cata = new DataTable();

            cata = sp.SelectCMD_TMP_CAT_FILES();

            if (cata.Rows.Count > 0)
            {
                string filezip = (string)cata.Rows[0]["FULL_FILENAME"];
                FileInfo finf = new FileInfo(filezip);
                string catalogozip = finf.Name.Substring(0, (finf.Name.IndexOf("_")));
                string datezip = finf.Name.Substring(finf.Name.LastIndexOf("_") + 1, (finf.Name.Length - 5 - finf.Name.LastIndexOf("_")));
                long dateLongzip = -1;

                try
                {
                    dateLongzip = Convert.ToInt64(datezip);
                }
                catch {}


                try
                {
                    
                    this.cargaCurrentCatalogos(dirTemp, filezip, catalogozip, dateLongzip);


                }

                catch {
                    Errores++;
                    this.addText("- Error en la carga del archivo : " + filezip + "\n");
                    return false;
                }
            }
            else
            {
                this.addText("- No se llevo a cabo la sincronizacion debido a que ya se tiene la ultima version actualizada\n");
                return false;
            }

            
           return true;
            
        }
        private string[] listarArchivos(String dir, string filtro)
        {
            string[] directorios = new string[0];
            try
            {
                directorios = Directory.GetFiles(dir, filtro, SearchOption.AllDirectories);
                
            }
            catch (Exception)
            {
                Errores++;
                directorios = new string[0];
                this.addText("Error en la obtencion de los archivos de la carpeta compartida\n");
            }
            return directorios;
        }
        private void cargaCurrentCatalogos(string tmpFile, string file, string catalogo, long dateLong)
        {
            FileInfo finf = new FileInfo(file);
            tmpFile = tmpFile + "\\" + finf.Name;

            if (this.copiarArchivo(file, tmpFile))
            {
                
                if (comprobacionDescargaArchivo(file, tmpFile))
                {
                    
                    sp.InsertCMD_CURRENT_CAT_FILES(tmpFile, catalogo, dateLong, true);
                    this.addText("- Archivo descargado correctamente : " + tmpFile);
                    this.descomprimir(tmpFile);
                    
                    

                }
            }
        }
        private bool copiarArchivo(string sourceDirName, string destDirName)
        {
            try
            {
                //this.addText("Copiando archivo " + sourceDirName + " a carpeta temporal " + destDirName + "\n");
                FileInfo finf = new FileInfo(destDirName);
                if (!Directory.Exists(finf.DirectoryName))
                    Directory.CreateDirectory(finf.DirectoryName);
                File.Copy(sourceDirName, destDirName, true);
                return true;
            }
            catch (Exception ex)
            {
                //this.addText("Error intentando copiar archivo " + sourceDirName + " a carpeta temporal " + destDirName + "\n" + ex.Message);
                return false;
            }
        }
        private bool comprobacionDescargaArchivo(string source, string target)
        {

            if (File.Exists(target))
            {
                FileInfo finfSource = new FileInfo(source);
                FileInfo finfTarget = new FileInfo(target);
                if (finfSource.Length == finfTarget.Length)
                    return true;
                else
                {
                    //this.addText("Se registró una diferencia mientras se comprobaba la descarga entre " + source + " y " + target + "\n");
                    return false;
                }

            }
            return false;


        }
        private List<string> descomprimir(string file)
        {
            FileInfo finf = new FileInfo(file);
            return ZipUtil.UnZipFiles(file, finf.DirectoryName, null, false);
            //CompressionEngine.SetOptions(@"Some other location");
            //CompressionEngine.Current.Decoder.DecodeIntoDirectory
        }

        private bool CargaArchivosTxt(string dir, string filtro)
        {
            /// ---------------------- Obtiene Archivos txt --------------------------- ///
            bool valida = true;
            string[] archivosTerritorio = this.listarArchivos(dir, filtro);

            if (archivosTerritorio.Length == 0)
            {
                this.addText("- No se encontraron archivos de catalos en :" + dir + "\n");
                return false;
            }

            //Registra los archivos que seran cargados a la base de datos
            foreach (string file in archivosTerritorio)
            {
                try
                {
                    FileInfo fkpi = new FileInfo(file);
                    string catalogo = fkpi.Name;
                    //string date = file.Substring(file.LastIndexOf("_") + 1, (file.Length - 5 - file.LastIndexOf("_")));
                    long dateLong = -1;
                    try
                    {
                        dateLong = Convert.ToInt64(DateTime.Now);
                    }
                    catch { }

                    sp.InsertCMD_TMP_CAT_FILES(file, catalogo, dateLong);
                    this.addText("- " + file +"\n");
                }
                catch (Exception ex)
                {
                    Errores++;
                    this.addText("- Error en lectura de archivo " + file + "\n" + ex.Message);
                }
            }


            DataTable kpis = new DataTable();
            kpis = sp.SelectCMD_TMP_CAT_FILES();
            if (kpis.Rows.Count == 0)
                return false;

            foreach (DataRow g in kpis.Rows)
            {
                string file = (string)g["FULL_FILENAME"];
                string kpi = (string)g["CATALOG_NAME"];
                long dateLong = (long)g["FILENAME_DATE"];
                //this.cargaCurrentFilesPrueba(file, kpi, dateLong);
                try
                {
                    this.cargaCurrentFiles(file, kpi, dateLong); //carga a temporal la informacion mediante bulkinsert
                    sp.InsertCMD_CURRENT_CAT_FILES(file, kpi, dateLong, true); //registro exitoso de carga
                    this.addText("- Actualizacion exitosa de archivo : " + file + "\n");

                }
                catch (Exception ex)
                { //Insertar codigo de error
                    Errores++;
                    sp.InsertCMD_CURRENT_CAT_FILES(file, kpi, dateLong, false); //registro exitoso de carga
                    this.addText("- Error en actualizacion de archivo : " + file + "\n" + "- - Error :" + ex.Message.ToString() + "\n" );
                }

            }


           
                return true;
           
        }

        private void spBtnCerrar_MouseUp(object sender, MouseButtonEventArgs e)
        {
            this.Close();
        }
        private void eliminarArchivos(String dir, string filtro)
        {
            if (Directory.Exists(dir))
            {

                string[] filePaths = Directory.GetFiles(dir, filtro, SearchOption.AllDirectories);
                foreach (string filePath in filePaths)
                    File.Delete(filePath);
                string[] dirPaths = Directory.GetDirectories(dir);
                foreach (string path in dirPaths)
                {
                    if (path != dir)
                        Directory.Delete(path);
                }
            }

        }

        private void cargaCurrentFiles(string file, string kpi, long dateLong)
        {

            FileInfo finf = new FileInfo(file);
            string tabla = "";
            switch (finf.Name)
            {
                case "Banco.txt":
                    tabla = "STG_CMD_BANCO";
                    break;
                case "centro_logistico.txt":
                    tabla = "STG_CMD_CLO";
                    break;
                case "frecuencia.txt":
                    tabla = "STG_CMD_FECUENCIA";
                    break;
                case "iva.txt":
                    tabla = "STG_CMD_IVA";
                    break;
                case "lead_time.txt":
                    tabla = "STG_CMD_LEADTIME";
                    break;
                case "medios_colocacion.txt":
                    tabla = "STG_CMD_MEDIOCOLOCACION";
                    break;
                case "regiones.txt":
                    tabla = "STG_CMD_REGION";
                    break;
                case "tipo_negocio.txt":
                    tabla = "STG_CMD_TIPO_NEGOCIO";
                    break;
                case "cat_localidad.txt":
                    tabla = "STG_CMD_LOCALIDAD";
                    break;
                case "CAT_Sepomex.txt":
                    tabla = "STG_CMD_SEPOMEX";
                    break;
                case "CAT_VARIOS.txt":
                    tabla = "STG_CMD_VARIOS";
                    break;
                case "cat_grupoclientes4.txt":
                    tabla = "STG_CMD_GRUPOCLIENTES4";
                    break;
                case "sys_tipo_persona_fiscal.txt":
                    tabla = "STG_CMD_TIPO_PERSONA_FISCAL";
                    break;

            }

           
                sp.ExecuteBulkInsert(tabla, file);
                sp.ExecuteSQLUpdateCatalogos(tabla);
           


        }



    }

}
